///*
// * MineralKineticsDatabase.cpp
// *
// *  Created on: 15 Jul 2011
// *      Author: al2010
// */
//
//#include "MineralKineticsDatabase.h"
//
//// C++ includes
//#include <cmath>
//#include <iostream>
//#include <fstream>
//using namespace std;
//
//// Boost includes
//#include <boost/foreach.hpp>
//#include <boost/algorithm/string.hpp>
//
//// GeoReact includes
//#include "Utils/StringUtils.h"
//
//const MineralKineticsDatabase::MineralKineticsInfoList& MineralKineticsDatabase::GetMineralKineticsInfoList() const
//{
//	return mineralRateInfoList;
//}
//
//const MineralKineticsDatabase& MineralKineticsDatabase::GetInstance()
//{
//	static MineralKineticsDatabase db;
//	
//	return db;
//}
//
//const MineralKineticsInfo MineralKineticsDatabase::GetMineralKineticsInfo(const string& mineralName) const
//{
//	const optional<MineralKineticsInfo> mineralRateInfo = FindMineralKineticsInfo(mineralName);
//	
//	// Check if the mineral rate information of the given species has been successfully found in the database
//	if(!mineralRateInfo)
//	{
//		cerr << "Error: Cannot retrieve mineral rate information of the mineral " << mineralName << ". There is no such mineral in the mineral rate database." << endl; exit(0);
//	}
//	
//	return *mineralRateInfo;
//}
//
//const optional<MineralKineticsInfo> MineralKineticsDatabase::FindMineralKineticsInfo(const string& mineralName) const
//{
//	auto iterMineralRateInfo = std::find_if(mineralRateInfoList.begin(), 
//			                                mineralRateInfoList.end(), 
//			                                [&](const MineralKineticsInfo& info) { return info.mineralName == mineralName; });
//	
//	if(iterMineralRateInfo != mineralRateInfoList.end())
//		return optional<MineralKineticsInfo>(*iterMineralRateInfo);
//	else
//		return optional<MineralKineticsInfo>();
//}
//
//const double MineralKineticsDatabase::GetFromLineSpecificSurfaceArea(const string& surfAreaLine) const
//{
//	vector<string> splitLine = Split(surfAreaLine, " =");
//	
//	return atof(splitLine[1].c_str());
//}
//
//const string MineralKineticsDatabase::GetFromLineMechanismName(const string& mechanismLine) const
//{
//	vector<string> splitLine = Split(mechanismLine, " :");
//	
//	return splitLine[0];
//}
//
//const double MineralKineticsDatabase::GetFromLineRateConstant(const string& mechanismLine) const
//{
//	vector<string> splitLine = Split(mechanismLine, " =;");
//	
//	auto iter = std::find(splitLine.begin(), splitLine.end(), "log(k)"); 
//	
//	if(iter != splitLine.end())
//		return std::pow(10.0, atof((++iter)->c_str()));
//	else
//		return 0.0;
//}
//
//const double MineralKineticsDatabase::GetFromLineActivationEnergy(const string& mechanismLine) const
//{
//	vector<string> splitLine = Split(mechanismLine, " =;");
//	
//	auto iter = std::find(splitLine.begin(), splitLine.end(), "Ea"); 
//	
//	if(iter != splitLine.end())
//		return atof((++iter)->c_str());
//	else
//		return 0.0;
//}
//
//const vector<MineralCatalyst> MineralKineticsDatabase::GetFromLineCatalysts(const string& mechanismLine) const
//{
//	vector<string> splitLine = Split(mechanismLine, " =;:{,}");
//	
//	auto iter = std::find(splitLine.begin(), splitLine.end(), "catalysts"); 
//	
//	vector<MineralCatalyst> catalysts;
//	
//	if(iter != splitLine.end())
//	{
//		vector<string> splitSubline(++iter, splitLine.end());
//		
//		for(unsigned i = 0; i < splitSubline.size(); i += 3)
//		{
//			MineralCatalyst catalyst;
//			
//			string quantityName     = splitSubline[i];
//			string catalystName     = splitSubline[i + 1];
//			string quantityExponent = splitSubline[i + 2];
//			
//			catalyst.quantityName     = quantityName;
//			catalyst.quantityExponent = atof(quantityExponent.c_str());
//			catalyst.catalystName     = catalystName;
//			
//			// Check if the 
//			catalysts.push_back(catalyst);
//		}
//	}
//	
//	return catalysts;
//}
//
//const MineralMechanism MineralKineticsDatabase::GetFromLineMechanism(const string& mechanismLine) const
//{
//	MineralMechanism mechanism;
//	
//	mechanism.mechanismName = GetFromLineMechanismName(mechanismLine);
//	mechanism.k             = GetFromLineRateConstant(mechanismLine);
//	mechanism.Ea            = GetFromLineActivationEnergy(mechanismLine);
//	mechanism.catalysts     = GetFromLineCatalysts(mechanismLine);
//	
//	return mechanism;
//}
//
//MineralKineticsDatabase::MineralKineticsDatabase()
//{
//	ifstream file("Databases/mineral.dtb");
//	
//	if(!file) { cout << "Error: could not open file " << "mineral.dtb" << "." << endl; exit(1); }
//	
//	// The String object that will hold the current line in the file to be processed 
//	string line; 
//	
//	// Loop over all the lines of the file
//	while(!file.eof())
//	{
//		// Get the current line of the file and clean it by removing all the left/right white spaces
//		std::getline(file, line); boost::trim(line);
//		
//		// Check if the current line is a comment line and if so, continue in the next line
//		if(line[0] == '#')
//			continue;
//		
//		// Check if the current line begins a new mineral rate block
//		if(line[0] == '-')
//		{
//			// The new mineral rate info to be set up
//			MineralKineticsInfo mineralRateInfo;
//			
//			// Set the name of the mineral; note that we eliminate the first char of the line, which is '-'
//			mineralRateInfo.mineralName.assign(++line.begin(), line.end());
//			
//			// Get the next line of the file, which should contain the specific surface area of the mineral
//			std::getline(file, line);
//			
//			// Read the specific surface area in the current line
//			mineralRateInfo.specificSurfaceArea = GetFromLineSpecificSurfaceArea(line);
//			
//			// Loop over all the next lines until an empty line is found
//			while(true)
//			{
//				// Before getting a new line of the file, check if the end of file has been achieved
//				if(file.eof())
//					break;
//				
//				// Get the next line of the file, which should contain a rate mechanism or an empty line
//				std::getline(file, line);
//				
//				// Check if the current line is an empty line, which indicates that there is no more mechanisms for the current mineral
//				if(line == "")
//					break;
//				
//				// Read the rate mechanim in the current line 
//				mineralRateInfo.mechanisms.push_back( GetFromLineMechanism(line) );
//			}
//			
//			// Add the new created mineral rate info into the container of mineral rates info
//			mineralRateInfoList.push_back(mineralRateInfo);
//		}
//	}
//}
